﻿using System;
using System.ComponentModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
using System.Net;
using KWS.SPWeather.MetOffice;

namespace KWS.SPWeather.SPWeatherWebPart
{   
    /// <summary>
    /// Has to be Sharepoint Webpart and not a standard WebPart to handle the ToolPart.
    /// </summary>
    [ToolboxItemAttribute(true)]
    public class SPWeatherWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private string _accountKey;        
        private string _site;
        private int _siteId;

        /// <summary>
        /// Microsoft Azure Data Market Primary Account Key
        /// </summary>
        [Personalizable(PersonalizationScope.User)]
        public string AccountKey
        {
            get
            {
                return _accountKey;
            }

            set
            {
                _accountKey = value;
            }
        }        

        /// <summary>
        /// Met Office SiteName.
        /// </summary>
        [Personalizable(PersonalizationScope.User)]
        public string SiteName
        {
            get
            {
                return _site;
            }

            set
            {
                _site = value;
            }
        }     

        /// <summary>
        /// Create the custom Edit Web Part pane.
        /// </summary>
        /// <returns></returns>
        public override ToolPart[] GetToolParts()
        {
            ToolPart[] allToolParts = new ToolPart[3];
            WebPartToolPart standardToolParts = new WebPartToolPart();
            CustomPropertyToolPart customToolParts = new CustomPropertyToolPart();
            SPWeatherToolPart spWeatherToolParts = new SPWeatherToolPart()
            {
                AccountKey = _accountKey,
                SiteName = _site
            };
            allToolParts[0] = standardToolParts;
            allToolParts[1] = customToolParts;
            allToolParts[2] = spWeatherToolParts;                     

            return allToolParts;
        }

        /// <summary>
        /// Retrieve and render the weather forecast.
        /// </summary>
        protected override void CreateChildControls()
        {
            
            Table table;
            TableRow tr;
            TableCell td;

            CssRegistration.Register(SPContext.Current.Site.Url + "/style library/spweather/styles.css");

            if (!string.IsNullOrEmpty(_site))
            {
                _siteId = 0;
                int.TryParse(_site.Substring(_site.IndexOf("(") + 1, _site.IndexOf(")") - (_site.IndexOf("(") + 1)), out _siteId);
            }
            if (!string.IsNullOrEmpty(_accountKey))
                if (_siteId > 0)
                {
                    Uri serviceUri = new Uri("https://api.datamarket.azure.com/DataGovUK/MetOfficeWeatherOpenData/");
                    DataGovUKMetOfficeWeatherOpenDataContainer metOffice = new DataGovUKMetOfficeWeatherOpenDataContainer(serviceUri);
                    metOffice.Credentials = new NetworkCredential(_accountKey, _accountKey);
                    try
                    {
                        var significantWeathers = metOffice.SignificantWeather
                            .Take(33)
                            .ToList();    

                        var forecasts = metOffice.DailyForecast
                            .Where(f => f.ForecastSiteCode == _siteId
                                && f.Date >= DateTime.Today)
                            .OrderBy(f => f.ID)
                            .Take(5)
                            .ToList();
                        table = new Table() { CssClass = "spweather", CellPadding = 0, CellSpacing = 0 };
                        tr = new TableRow();
                        td = new TableCell();
                        TableHeaderRow trHeader = new TableHeaderRow();

                        foreach (DailyForecast forecast in forecasts)
                        {
                            var significantWeather = significantWeathers
                                .Where(sw => sw.Code == forecast.SignificantWeatherIdDay)
                                .FirstOrDefault();

                            Table tableDay = new Table() { CellPadding = 0, CellSpacing = 0 };
                            TableRow trDay = new TableRow();
                            TableCell tdDay = new TableCell();
                            TableHeaderCell tdHeader = new TableHeaderCell();

                            if (forecast.Date.AddHours(Convert.ToDouble(forecast.TimeStep)).Day == DateTime.Now.Day)
                                tdHeader.Text = "Today";
                            else if (forecast.Date.AddHours(Convert.ToDouble(forecast.TimeStep)).Day == DateTime.Now.AddDays(1).Day)
                                tdHeader.Text = "Tomorrow";
                            else
                                tdHeader.Text = forecast.Date.AddHours(Convert.ToDouble(forecast.TimeStep)).DayOfWeek.ToString();
                            tdHeader.Scope = TableHeaderScope.Column;
                            trHeader.Cells.Add(tdHeader);

                            tdDay = new TableCell();
                            tdDay.RowSpan = 2;
                            tdDay.ToolTip = significantWeather.Description;
                            tdDay.CssClass = significantWeather.Description.Replace(" ", "_").Replace("(", "").Replace(")", "");
                            trDay.Cells.Add(tdDay);

                            tdDay = new TableCell() { CssClass = "max" };
                            tdDay.Text = "Max: " + Convert.ToInt32(forecast.FeelsLikeTemperatureDay).ToString() + (char)176 + "C";
                            trDay.Cells.Add(tdDay);
                            tableDay.Rows.Add(trDay);

                            trDay = new TableRow();
                            tdDay = new TableCell() { CssClass = "min" };
                            tdDay.Text = "Min: " + Convert.ToInt32(forecast.FeelsLikeTemperatureNight).ToString() + (char)176 + "C";
                            trDay.Cells.Add(tdDay);
                            tableDay.Rows.Add(trDay);

                            tableDay.Rows.Add(trDay);

                            td = new TableCell();
                            td.Controls.Add(tableDay);
                            tr.Cells.Add(td);
                        }
                        table.Rows.Add(trHeader);
                        table.Rows.Add(tr);
                        this.Controls.Add(table);
                    }
                    catch (Exception ex)
                    {
                        this.Controls.Add(new Literal() { Text = "There was a problem accessing the Met Office data." });
                        return;
                    }
                }
                else
                {
                    this.Controls.Add(new Literal() { Text = "Please edit the web part and enter a location." });
                }
            else
            {
                this.Controls.Add(new Literal() { Text = "Please edit the web part and enter a Microsoft Azure Data Market Account Key." });
            }            
        }
    }
}
